﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Trentacular.SharePoint.Deployment.Collections
{
    /// <summary>
    /// A generic list wrapper that exposes all methods and properties as virtual
    /// </summary>
    public class VirtualList<T> : IList<T>, IList
    {
        private List<T> BackingList;

        public VirtualList()
        {
            BackingList = new List<T>();
        }

        public VirtualList(int capacity)
        {
            BackingList = new List<T>(capacity);
        }

        public VirtualList(IEnumerable<T> collection)
        {
            BackingList = new List<T>(collection);
        }

        public VirtualList(List<T> backingList)
        {
            BackingList = backingList;
        }

        #region IList<T> Members

        public virtual int IndexOf(T item)
        {
            return BackingList.IndexOf(item);
        }

        public virtual void Insert(int index, T item)
        {
            BackingList.Insert(index, item);
        }

        public virtual void RemoveAt(int index)
        {
            BackingList.RemoveAt(index);
        }

        public virtual T this[int index]
        {
            get
            {
                return BackingList[index];
            }
            set
            {
                BackingList[index] = value;
            }
        }

        #endregion

        #region ICollection<T> Members

        public virtual void Add(T item)
        {
            BackingList.Add(item);
        }

        public virtual void Clear()
        {
            BackingList.Clear();
        }

        public virtual bool Contains(T item)
        {
            return BackingList.Contains(item);
        }

        public virtual void CopyTo(T[] array, int arrayIndex)
        {
            BackingList.CopyTo(array, arrayIndex);
        }

        public virtual int Count
        {
            get { return BackingList.Count; }
        }

        public virtual bool IsReadOnly
        {
            get { return ((IList)BackingList).IsReadOnly; }
        }

        public virtual bool Remove(T item)
        {
            return Remove(item);
        }

        #endregion

        #region IEnumerable<T> Members

        public virtual IEnumerator<T> GetEnumerator()
        {
            return BackingList.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }

        #endregion

        #region IList Members

        public virtual int Add(object value)
        {
            return ((IList)BackingList).Add(value);
        }

        public virtual bool Contains(object value)
        {
            return ((IList)BackingList).Contains(value);
        }

        public virtual int IndexOf(object value)
        {
            return ((IList)BackingList).IndexOf(value);
        }

        public virtual void Insert(int index, object value)
        {
            ((IList)BackingList).Insert(index, value);
        }

        public virtual bool IsFixedSize
        {
            get { return ((IList)BackingList).IsFixedSize; }
        }

        public virtual void Remove(object value)
        {
            ((IList)BackingList).Remove(value);
        }

        object IList.this[int index]
        {
            get
            {
                return this[index];
            }
            set
            {
                this[index] = (T)value;
            }
        }

        #endregion

        #region ICollection Members

        public virtual void CopyTo(Array array, int index)
        {
            ((IList)BackingList).CopyTo(array, index);
        }

        public virtual bool IsSynchronized
        {
            get { return ((IList)BackingList).IsSynchronized; }
        }

        public virtual object SyncRoot
        {
            get { return ((IList)BackingList).SyncRoot; }
        }

        #endregion
    }

    /// <summary>
    /// An array list wrapper that exposes all methods and properties as virtual
    /// </summary>
    public class VirtualList : IList
    {
        private ArrayList BackingList;

        public VirtualList()
        {
            BackingList = new ArrayList();
        }

        public VirtualList(ICollection c)
        {
            BackingList = new ArrayList(c);
        }

        public VirtualList(int capacity)
        {
            BackingList = new ArrayList(capacity);
        }

        public VirtualList(ArrayList backingList)
        {
            BackingList = backingList;
        }

        #region IList Members

        public virtual int Add(object value)
        {
            return BackingList.Add(value);
        }

        public virtual void Clear()
        {
            BackingList.Clear();
        }

        public virtual bool Contains(object value)
        {
            return BackingList.Contains(value);
        }

        public virtual int IndexOf(object value)
        {
            return BackingList.IndexOf(value);
        }

        public void Insert(int index, object value)
        {
            BackingList.Insert(index, value);
        }

        public virtual bool IsFixedSize
        {
            get { return BackingList.IsFixedSize; }
        }

        public virtual bool IsReadOnly
        {
            get { return BackingList.IsReadOnly; }
        }

        public virtual void Remove(object value)
        {
            BackingList.Remove(value);
        }

        public virtual void RemoveAt(int index)
        {
            BackingList.RemoveAt(index);
        }

        public virtual object this[int index]
        {
            get
            {
                return BackingList[index];
            }
            set
            {
                BackingList[index] = value;
            }
        }

        #endregion

        #region ICollection Members

        public virtual void CopyTo(Array array, int index)
        {
            BackingList.CopyTo(array, index);
        }

        public virtual int Count
        {
            get { return BackingList.Count; }
        }

        public virtual bool IsSynchronized
        {
            get { return BackingList.IsSynchronized; }
        }

        public virtual object SyncRoot
        {
            get { return BackingList.SyncRoot; }
        }

        #endregion

        #region IEnumerable Members

        public virtual IEnumerator GetEnumerator()
        {
            return BackingList.GetEnumerator();
        }

        #endregion
    }
}
